import logging

import sys
sys.coinit_flags = 0
import platform
import wmi
import pythoncom     #使得wmi可以在线程中执行
import CSCommunication
import Security
import BackDoorDetect
import psutil
import RegrystGet
import winreg
from Login import *

##############
#author:张子路#
##############

class Function():
    def __init__(self):
        pythoncom.CoInitialize()           #使win32接口可以在多线程中调用，为线程创建com对象
        self.wmiobj = wmi.WMI()
        self.ParaNumber=0
        try:
            self.Communcate=CSCommunication.CSCommunication()
        except Exception as e:
            logging.error("连接文件CSCommunication.py失败 {0}".format(e), exc_info=True)
        try:
            self.SecurityCheck=Security.Security()    #调用安全策略检查文件
        except Exception as e:
            logging.error("连接文件Security.py失败 {0}".format(e), exc_info=True)
        try:
            self.BackDoorCheck=BackDoorDetect.BackDoorDetect()   #调用后门检测文件
        except Exception as e:
            logging.error("连接文件BackDoorDetect.py失败 {0}".format(e), exc_info=True)
        try:
            self.SelfRunCheck=RegrystGet.RegrystGet()     #调用获取注册表文件
        except Exception as e:
            logging.error("连接文件RegrystGet.py失败 {0}".format(e), exc_info=True)

    def Close(self):
        pythoncom.CoUninitialize()         #去初始化

    def HaddleMCheck(self,id,CheckList):
        self.Result=[]
        re='\n'
        try:                  #调用相应的函数来获取对应的核查信息
            if CheckList[0]==1:
                re=re+self.HostCheckHaddle()+"\n"
            if CheckList[1]==1:
                re=re+self.SecurityCheckHaddle()+"\n"
            if CheckList[2]==1:
                re=re+self.PatchCheckHaddle()+"\n"
            if CheckList[3]==1:
                re=re+self.NetCheckHaddle()+"\n"
            if CheckList[4]==1:
                re=re+self.BackDoorCheckHaddle()+"\n"
            if CheckList[5]==1:
                re=re+self.SelfRunCheckHaddle()+"\n"
            if CheckList[6]==1:
                re=re+self.SoftWareCheckHaddle()+"\n"
                #self.workbook.save('Excel_submit.xls')
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)
        finally:
            self.Close()
            self.ParaNumber=0
            if id!=-1:
                self.Send(id,self.Result)        #发送检测结果
            return re

    def Send(self,id,Result):
        try:
            self.Communcate.SendOutPut(id,Result)       #发送检测结果
        except Exception as e:
            logging.error("发送检测结果失败 {0}".format(e), exc_info=True)

    def HostCheckHaddle(self):

        HostCheckOut='主机信息核查:\n'            #核查主机信息
        try:
            str='请检查设备运行环境是否符合要求。'
            HostMachine=platform.machine()    #计算机类型，'x86'
            HostCheckOut=HostCheckOut+'计算机类型:    {0}\n加固建议：   {1}\n'.format(HostMachine,str)
            self.Result.append(['主机信息核查','计算机类型',HostMachine,str])
            HostPlatform=platform.platform()   #获取操作系统名称及版本号，'Windows-7-6.1.7601-SP1'
            HostCheckOut=HostCheckOut+'操作系统及版本:    {0}\n加固建议：   {1}\n'.format(HostPlatform,str)
            self.Result.append(['主机信息核查','操作系统及版本',HostPlatform,str])
            HostArchitecture=platform.architecture()   #获取操作系统的位数，('32bit', 'WindowsPE')
            HostCheckOut=HostCheckOut+'操作系统位数:    {0}\n加固建议：   {1}\n'.format(HostArchitecture[0],str)
            self.Result.append(['主机信息核查','操作系统位数',HostArchitecture[0],str])
            HostProcessor=platform.processor()  #计算机处理器信息，'x86 Family 16 Model 6 Stepping 3, AuthenticAMD'
            HostCheckOut=HostCheckOut+'处理器信息:    {0}\n加固建议：   {1}\n'.format(HostProcessor,str)
            self.Result.append(['主机信息核查','处理器信息',HostProcessor,str])
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)
        return HostCheckOut+'\n'


    def SecurityCheckHaddle(self):

        SecuityCheckOut='安全策略检查:\n'
        try:

            Result=self.SecurityCheck.SecurityCheck()           #调用安全策略核查文件获取安全策略核查结果


            ResultStr=''
            for iteam in Result:
                self.Result.append(['安全策略核查',iteam[0],iteam[1],iteam[2]])
                ResultStr=ResultStr+'已核查安全策略{0},检查结果为:{1}\n加固建议:{2}\n'.format(iteam[0],iteam[1],iteam[2])

            SecuityCheckOut=SecuityCheckOut+ResultStr
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)
        return SecuityCheckOut+'\n'

    def PatchCheckHaddle(self):

        PatchCheckOut='补丁信息核查:\n'         #进行补丁信息核查
        try:
            QuickFixEngineering = self.wmiobj.Win32_QuickFixEngineering() #用于获取windows更新补丁相关信息
            str='请查看补丁信息是否符合规定。'
            for iteam in QuickFixEngineering:
                Res='补丁信息:Caption={0},描述:{1},HotFixID={2},InstalledBy={3},安装日期:{4}' .format(iteam.Caption,
                                                                                              iteam.Description,iteam.HotFixID,
                                                                                              iteam.InstalledBy,iteam.InstalledOn)
                PatchCheckOut=PatchCheckOut+Res+'\n'+'加固建议：   {0}\n'.format(str)
                self.Result.append(['补丁信息核查','补丁信息',Res,str])
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

        return PatchCheckOut+'\n'


    def NetCheckHaddle(self):

        NetCheckOut='网络信息核查:\n'        #进行网络信息核查
        try:
            str='请检查网络信息是否符合规定。'
            HostNode=platform.node()       #计算机的网络名称，'Natural-PC'
            res='计算机名称为:{0}'.format(HostNode)
            NetCheckOut=NetCheckOut+res+'\n'
            self.Result.append(['网络信息核查','计算机名称',res,'无'])
            NetworkAdapterConfiguration  = self.wmiobj.Win32_NetworkAdapterConfiguration (IPEnabled=1) #用于配置及获取网络连接相关信息
            for iteam in NetworkAdapterConfiguration:
                res='网络信息:IPAddress={0},IPEnabled={1},ServiceName={2}'.format(iteam.IPAddress,iteam.IPEnabled,iteam.ServiceName)
                NetCheckOut=NetCheckOut+res+'\n'+'加固建议:{0}\n'.format(str)
                self.Result.append(['网络信息核查','网络信息核查',res,str])
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

        return NetCheckOut+'\n'

    def BackDoorCheckHaddle(self):

        SystemCheckOut='后门检测:\n'
        try:
            Shadow=self.BackDoorCheck.ShadowAccount()       #调用后门检测文件完成影子账户核查

            if Shadow==[]:
                res='无影子账户。'
                SystemCheckOut=SystemCheckOut+res
                self.Result.append(['后门核查','影子账户检测',res,'无'])
            else:
                res="存在影子账户:"
                for iteam in Shadow:
                    res=res+iteam+';'
                SystemCheckOut=SystemCheckOut+res+'\n'+'加固建议：删除影子账户。\n'
                self.Result.append(['后门核查','影子账户检测',res,'删除影子账户。'])
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

        return SystemCheckOut+'\n'


    def SelfRunCheckHaddle(self):

        SelfRunCheckOut='自启动项核查:\n'
        str='请检查自启动项是否符合规定。'          #寻找注册表RUN,RUNONCE项，获取自启动项
        try:
            RegistKey={winreg.HKEY_LOCAL_MACHINE:[r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run",r"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"],
               winreg.HKEY_CURRENT_USER:[r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run",r"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"]}
            CheckResult=self.SelfRunCheck.RegistryValueGet(RegistKey)
            for k, v in CheckResult.items():
                res='自启动项：'+k+ "："+ v
                SelfRunCheckOut=SelfRunCheckOut+res+'\n'+'加固建议: {0}\n'.format(str)
                self.Result.append(['自启动项核查','自启动核查',res,str])
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

        return SelfRunCheckOut+'\n'

    def SoftWareCheckHaddle(self):

        ServiceCheckOut='系统服务核查:\n'          #系统服务核查
        str='请检查服务是否符合规定。'
        count=0
        try:
            for item in list(psutil.win_service_iter()):
                res='服务名称:{0};启动方式:{1};运行状态:{2}'.format(item.name(),item.start_type(),item.status())
                ServiceCheckOut=ServiceCheckOut+res+'\n'+'加固建议: {0}\n'.format(str)
                self.Result.append(['服务项核查','服务信息',res,str])
                count+=1
                if count==10:
                    break
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

        return ServiceCheckOut+'\n'


if __name__ =="__main__":
    login=LoginStart()
    login.start()